리액트 프로젝트 셋업
리액트를 사용하는 프로젝트를 생성할 때 마다 create-react-app(이하 CRA)를 사용하게 되었었는데요, scratch 부터 자주 사용하는 구성을 템플릿으로 남겨두고 싶은 마음이 생겼습니다. 기본적으로 사용되는 React, typescript, webpack, babel, eslint, prettier 설정입니다.
각각의 항목들에 대해서 자세하기 다루기 보다는 사용할 수 있는 형태의 코드를 제공하는게 목적입니다.
아래의 레포지토리에서 본 블로그의 코드 전체를 확인하실 수 있습니다.
https://github.com/Tolluset/react-pj-template
템플릿 개요
# 사용할 라이브러리 버전 react 17.0.2 typescript 4.5.5 webpack 5.68.0 babel 7.12.2 eslint 8.8.0 prettier 2.5.1
이번에 사용할 프로젝트 패키지입니다.
프로젝트 생성
mkdir react-pj-template cd react-pj-template yarn init -y // 초기 설정 스킵하여 디폴트 옵션으로 생성
프로젝트 생성할 디렉토리를 만들고 해당 디렉토리에서 yarn init 패키지 파일을 초기화해 줍니다.
디렉토리 및 index.html 생성
CRA에서 해주는 것처럼, public, src
디렉토리를 만들고 public
에 index.html
을 추가 해줍시다.
mkdir public src touch public/index.html
// public/index.html <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Title</title> </head> <body> <div id="root"></div> </body> </html>
<div id="root"><div>
부분이 우리의 리액트가 들어갈 자리가 되겠습니다.
React
yarn add react react-dom yarn add -D @types/react @types/react-dom
@types
는 실제로 타입 모듈을 임포트해서 사용하면 dependencies
에 설치해야 하지만 이 템플릿에서는 사용하지 않기에 devDependencies
에 설치합니다.
react-dom은 index.ts
에서 index.html
의 진입점에 렌더하기 위해 필요합니다.
// src/index.tsx import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root'), );
// src/App.tsx import React from 'react'; const App = () => { return <div>App</div>; }; export default App;
이 템플릿에서는 Function Component
기준으로 생성하겠습니다.
리턴타입에는React.FC
를 사용하지 않고 추론적으로 사용하겠습니다.
https://github.com/facebook/create-react-app/pull/8177
Typescript
yarn add -D typescript
타입스크립트를 추가했으니 tsconfig.json
도 추가해주겠습니다.
// tsconfig.json { "compilerOptions": { "target": "es5", "module": "es6", "strict": true, "jsx": "react", "moduleResolution": "node", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "lib": ["es6","dom"], "outDir": "./dist", }, "ts-node": { "compilerOptions": { "module": "CommonJs" } }, "include": ["src/**/*", "tests/**/*"], }
target
을 es5
로 하면 라이브러리들이 es6
를 쓰는 경우 컴파일 단계에서 에러가 날 수 있는데요, 이를 위해 lib에 es6
를 추가 해 둡니다. (target
을 es6
로 써도 되고요, IE
가 2022년 6월경 지원종료를 하는데 IE
이외의 대부분의 브라우저가 잘 지원하죠... https://caniuse.com/?search=es6 커버율 96.34%
?)
module
은 import, export
로 사용하고 싶기 때문에 es6
로 설정합니다.
strict
를 true
로 해두면 타입스크립트가 권장하는 여러 규칙들을 자동으로 추가해줍니다.
https://www.typescriptlang.org/tsconfig#strict
jsx
는 react
를 사용하기 때문에 그대로 사용합니다.
esModuleInterop
는 import * as A from A
를 import A from A
같이 default import를 사용할 수 있게 해줍니다.
moduleResolution
는 모듈 import를 어떻게 할 것이냐 node
의 경우 nodejs
가 사용하는 방식을 사용합니다.
moduleResolution
에 대한 자세한 내용은 아래의 링크가 도움이 될 것 같습니다.
좀 더 tsconfig
를 세밀조정하고 싶다면, 레퍼런스를 참조해주세요.
https://www.typescriptlang.org/tsconfig
Webpack
# tl;dr yarn add -D webpack webpack-cli webpack-dev-server babel-loader html-webpack-plugin clean-webpack-plugin ts-node @types/node @types/webpack @types/clean-webpack-plugin # webpack yarn add -D webpack webpack-cli webpack-dev-server # loader yarn add -D babel-loader # plugins yarn add -D html-webpack-plugin clean-webpack-plugin # types yarn add -D ts-node @types/node @types/webpack @types/clean-webpack-plugin
# webpack
: 웹팩을 사용하기 위한 cli와 개발환경에서 필요한 dev-server를 추가해줍니다.
# loader
: 코드에 대한 해석을 babel에게 맡깁니다.
# plugins
: html을 가져다 쓰기 위한 html-webpack-plugin
과 빌드 시 마다 빌드된 파일을 저장하는 폴더를 초기화 시켜주는 clean-webpack-plugin
을 사용합니다.
# types
: webpack.config.ts
를 사용하는게 ?하다 생각하기 때문에 를 사용하기 위함입니다. (.js
로 해도되는데 github에 js를 사용하고 있다고 나오는게 묘하게 거슬려요, 저만 그런가요??? ?)
// webpack.config.ts import path from "path"; import webpack from "webpack"; import HtmlWebpackPlugin from "html-webpack-plugin"; import { CleanWebpackPlugin } from "clean-webpack-plugin"; import ESLintPlugin from 'eslint-webpack-plugin'; import "webpack-dev-server"; const config: webpack.Configuration = { mode: "development", entry: "./src/index.tsx", module: { rules: [ { test: /\.(ts|tsx)$/, include: path.resolve(__dirname, 'src'), use: { loader: "babel-loader", }, }, ], }, resolve: { extensions: [".tsx", ".ts", ".js"], }, output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js", }, plugins: [ new HtmlWebpackPlugin({ template: "public/index.html", }), new CleanWebpackPlugin(), new ESLintPlugin({ extensions: ['ts', 'tsx'] }) ], }; export default config;
Babel
yarn add -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
사용할 preset들은 es6를 위해 사용하는 env
, 리액트를 위한 react
, 타입스크립트를 위한 typescript
를 추가해 줍니다.
// .babelrc { "presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ] }
ESLint
yarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-import-resolver-typescript eslint-webpack-plugin
React, typescript와 관련된 ESlint를 추가해서 사용합니다.
plugins
에 사용할 플러그인들을 정의 해두고, extends
에서 플러그인들이 프리셋으로 제공하는 기능들을 지정하여 사용할 수 있습니다.
// .eslintrc.json { "root": true, "env": { "browser": true, "es6": true }, "parser": "@typescript-eslint/parser", "parserOptions": { "project": ["./tsconfig.json"] }, "plugins": [ "@typescript-eslint", "react", "react-hooks", "import", "jsx-a11y" ], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "plugin:import/recommended", "plugin:react-hooks/recommended", "plugin:jsx-a11y/recommended" ], "settings": { "import/parsers": { "@typescript-eslint/parser": [".ts", ".tsx"] }, "import/resolver": { "typescript": { "project": "./tsconfig.json" } } }, "rules": { "no-console": "warn", "import/order": [ "error", { "groups": [ "builtin", "external", "internal", "parent", "sibling", "index", "object", "type" ] } ] } }
ESlint가 체크 할 필요 없는 파일은 .gitignore
처럼 아래와 같이 정의해주시면 됩니다.
// .eslintignore node_modules dist
위처럼 설정한 eslint를 webpack dev server에 연결하면
// webpack.cofing.ts // ...omit plugins: [ ... new ESLintPlugin({ extensions: ['ts', 'tsx'] })
터미널에서 바로 확인 하실 수 있게 됩니다.
Prettier
yarn add -D prettier eslint-config-prettier
eslint-plugin-prettier
가 아닌 eslint-config-prettier
를 사용해줍니다.
ESlint 설정 파일의 extends
에 prettier 플러그인을 추가해줍니다.
// .eslintrc.json // ...omit { "extends": [ ... "prettier" ] }
extends
에 prettier
를 추가함으로써 eslint와 prettier가 충돌하지 않게 적절하게 이미 설정된 rule들을 꺼줍니다. 그러므로 extends
의 마지막에 추가해주세요!
https://github.com/prettier/eslint-config-prettier
// .prettierc { "tabWidth": 2, "useTabs": false, "semi": true, "singleQuote": true, "trailingComma": "all", "bracketSpacing": true, "parser": "typescript", "arrowParens": "always" }
singleQuote, tarilingComma, parser
이외의 설정은 기본값이지만 변경하지 않도록 주의하기 위해 의도적으로 표시해둡니다.
추가적인 옵션들은 아래의 링크를 참조해주세요.
// .prettierignore dist node_modules
포맷팅이 필요없는 파일은 적절하게 걸러줍니다.
에필로그
Webpack의 프로덕션 빌드, 환경 별 파일 분리 및 머지 같은 설정이나, https://webpack.kr/guides/production/
Husky, lint-staged를 이용해서 좀 더 영리하게 린팅, 포매팅,
환경변수 등등...
추가적인 설정을 더 해둬야 하긴 합니다 ?
본 블로그 게시글을 보시고 문의 사항이 있으신 분들은 클래스메소드코리아 ([email protected])로 연락 주시면 빠른 시일 내 담당자가 회신 드릴 수 있도록 하겠습니다 !